//
//  ServerController.m
//  BufferedSocket
//
//  Created by Rainer Kupke (rkupke@gmx.de) on Thu Jul 26 2001.
//  Copyright (c) 2001 Rainer Kupke.
//
//
// Modified by Jonathan Saggau for iPhone Pong Project
//
// This software is provided 'as-is', without any express or implied 
// warranty. In no event will the authors be held liable for any damages 
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose, 
// including commercial applications, and to alter it and redistribute it 
// freely, subject to the following restrictions:
//
//     1. The origin of this software must not be misrepresented; you must 
//        not claim that you wrote the original software. If you use this 
//        software in a product, an acknowledgment in the product 
//        documentation (and/or about box) would be appreciated but is not 
//        required.
//
//     2. Altered source versions must be plainly marked as such, and must
//        not be misrepresented as being the original software.
//
//     3. This notice may not be removed or altered from any source 
//        distribution.
//        

#import "ServerController.h"
#import "BufferedSocket.h"
#import "MutableDataBufferExtension.h"
#import "PongPrefs.h"
#import "Common.h"
#import <sys/socket.h>

extern PongPrefs *sharedPongPrefs;

@implementation ServerController

- (void)startListening
{
	LogMethod();
    theSocket = [[BufferedSocket alloc] initWithSocketType:SOCK_STREAM];

	int port = [sharedPongPrefs port];
	if (port > 0)
	{
		NSLog(@"Listening on port %i", port);
	    [theSocket listenOnPort: [sharedPongPrefs port]];
	    [NSThread detachNewThreadSelector: @selector(threadListen:) toTarget: self withObject:nil];	}
	else
	{
		[NSException raise:SOCKET_EX_LISTEN_FAILED 
                    format:SOCKET_EX_LISTEN_FAILED];
	}
}

- (void)stopListening
{
	LogMethod();
	[theSocket release]; theSocket = nil;
}

- (id) init
{
    [super init];
    theSocket=nil;
	messageReceived = [[NSString alloc] initWithFormat:@""];
    return self;
}

- (void) dealloc
{
    [theSocket release];
	[messageReceived release]; messageReceived = nil;
	[super dealloc];
}

- (NSString *)messageReceived
{
    return [[messageReceived retain] autorelease]; 
}
- (void)setMessageReceived:(NSString *)aMessageReceived
{
    if (messageReceived != aMessageReceived) {
        aMessageReceived = [aMessageReceived copy];
        [messageReceived release];
        messageReceived = aMessageReceived;
    }
}

- (void) threadListen: (id) dummy;
{	
	@try {
	    NSAutoreleasePool *apool=[[NSAutoreleasePool alloc] init];
	    while(1)
	    {
			LogMethod();
        
	        NSAutoreleasePool *apool2=[[NSAutoreleasePool alloc] init];
        
	        BufferedSocket *s;
        
	        s=[theSocket acceptConnectionAndKeepListening];
	        [NSThread detachNewThreadSelector: @selector(threadCommunicate:) toTarget: self withObject: s];
	        [apool2 release];
	    }
	    [apool release];
    }
    @catch (NSException * e) {
		if(nil != delegate && [delegate respondsToSelector:@selector(serverControllerDidBork:)])
			[delegate performSelectorOnMainThread:@selector(serverControllerDidBork:) withObject:e waitUntilDone:YES];
		else
			exit(1);
    }
    @finally {
        // <#statements#>
    }
}

- (void) threadCommunicate: (BufferedSocket*) sock
{
	
	@try {
	    NSAutoreleasePool *apool=[[NSAutoreleasePool alloc] init];
	    NSMutableData *message;
	    NSMutableData *segment;
	    NSString *strMsg;
	    while(1)
	    {
	        NSAutoreleasePool *apool2=[[NSAutoreleasePool alloc] init];
	        message=[sock readDataUpToString: PACKET_TAG];
	        strMsg=@"";        
	        while([message length])
	        {
	            NSString *str;
            
	            segment=[message getBytesUpToString: PACKET_TAG];
	            [segment increaseLengthBy: 1];
	            str=[NSString stringWithUTF8String: [segment bytes]];
	            strMsg=[strMsg stringByAppendingFormat: @"%@\n",str];
	        }
	        [self performSelectorOnMainThread:@selector(setMessageReceived:) withObject:strMsg waitUntilDone:YES];
	        [apool2 release];
	    }
	    [apool release];
    }
    @catch (NSException * e) {
		if(nil != delegate && [delegate respondsToSelector:@selector(serverControllerDidBork:)])
			[delegate performSelectorOnMainThread:@selector(serverControllerDidBork:) withObject:e waitUntilDone:YES];
		else
			exit(1);
    }
    @finally {
        // <#statements#>
    }
}

- (id)delegate
{
    //NSLog(@"in -delegate, returned delegate = %@", delegate);

    return delegate; 
}
- (void)setDelegate:(id)aDelegate
{
    //NSLog(@"in -setDelegate:, old value of delegate: %@, changed to: %@", delegate, aDelegate);
	delegate = aDelegate;
}

-(unsigned short)currentPort;
{
	unsigned short localport = [theSocket localPort];
	return localport;
}

@end
